package main

import (
	"golang.org/x/net/context"
	"log"
	"net/http"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"test/meth"
	"time"
)

func main() {
	cmd := startVueFrontend()
	defer killVueFrontend(cmd)

	// 配置路由
	http.Handle("/api/scan", corsMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		meth.ScanningDevice(w, r)
	})))
	http.Handle("/api/upgrade", corsMiddleware(http.HandlerFunc(meth.HandleUpgrade)))

	// 启动服务
	server := &http.Server{
		Addr: ":20100",
	}
	log.Println("前端地址: http://localhost:20101")
	if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		log.Fatal("Go 服务启动失败:", err)
	}
	log.Fatal(server.ListenAndServe())
	waitForShutdown(server)
}

func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusNoContent)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// 启动 Vue 前端
func startVueFrontend() *exec.Cmd {
	cmd := exec.Command("npm", "run", "serve")
	cmd.Dir = "./web" // 前端目录（假设是 ./web）
	cmd.Stdout = nil
	cmd.Stderr = nil

	if err := cmd.Start(); err != nil {
		log.Fatal("无法启动 Vue 前端:", err)
	}
	log.Println("Vue 前端已启动 (PID:", cmd.Process.Pid, ")")
	return cmd
}

// 关闭 Vue 前端
func killVueFrontend(cmd *exec.Cmd) {
	if cmd == nil || cmd.Process == nil {
		return
	}
	if err := cmd.Process.Kill(); err != nil {
		log.Println("关闭 Vue 前端失败:", err)
	} else {
		log.Println("Vue 前端已关闭")
	}
}

// 捕获退出信号（Ctrl+C 或 kill）
func waitForShutdown(server *http.Server) {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan

	log.Println("正在关闭服务...")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("强制关闭 Go 服务:", err)
	}
	log.Println("服务已关闭")
}
